import serial
from struct import *
import time
import pydub 
import pandas as pd
import numpy as np
import wave
import sys
from PyQt5.QtWidgets import QApplication, QWidget, QMainWindow
from test_gui import Ui_MainWindow

app = QApplication(sys.argv)
wnd = QMainWindow()
uiDesign = Ui_MainWindow()
uiDesign.setupUi(wnd)

uiDesign.pushButton.clicked.connect(lambda: DoWork())

# 扫描可用串口
from serial.tools.list_ports import comports
for port in comports():
    uiDesign.cmbPorts.addItem(port.name)
    # print("port.name: ",port.name)

def readWAV(f):
    """读取格式信息
    (声道数、量化位数、采样频率、采样点数、压缩类型、压缩类型的描述)
    """
    file = wave.open(f, "rb")
    # (nchannels, sampwidth, framerate, nframes, comptype, compname)
    params = file.getparams()
    nchannels, sampwidth, framerate, nframes = params[:4]
    print(nchannels, sampwidth, framerate, nframes)
    # nchannels通道数 = 2
    # sampwidth量化位数 = 2
    # framerate采样频率 = 48000
    # nframes采样点数 = 499712

    # 读取nframes个数据，返回字符串格式
    str_data = file.readframes(nframes)
    # print("11111", len(str_data))
    file.close()
    return str_data

def wav_to_np(f):
    """ 将字符串转换为数组, 得到一维的short类型的数组"""
    file = wave.open(f, "rb")
    params = file.getparams()
    # nchannels, nframes = params[:2]
    nchannels = params[0]
    nframes = params[3]
    strData = readWAV("../hm3/luyin.wav")
    # print(strData)
    wave_data = np.frombuffer(strData, dtype=np.short)
    # print(wave_data)

    # 赋值的归一化
    wave_data = wave_data * 100.0 / (max(abs(wave_data)))
    print("len(wave_data)", len(wave_data))

    # 整合左声道和右声道的数据
    wave_data = np.reshape(wave_data, [nframes, nchannels])
    # print("xx",wave_data)
    file.close()
    # wave_data.shape = (-1, 2)   # -1的意思就是没有指定,根据另一个维度的数量进行分割
    return wave_data

def readMP3(f):
    """读取mp3格式信息"""
    a = pydub.AudioSegment.from_mp3(f)   #  AudioSegment读取mp3文件
    # print(a)
    nchannels = a.channels   # nchannels通道数 = 2
    framerate = a.frame_rate    # framerate采样频率 = 48000
    nframes = int(a.frame_count())    # 采样点数 = 617400
    str_data = a.raw_data    # str_data二进制的, 而get_array_of_samples()返回正常数值
    return nchannels, framerate, nframes

def mp3_to_np(f, normalized=False):
    """MP3 to numpy array"""
    a = pydub.AudioSegment.from_mp3(f)   
    # print(a.get_array_of_samples())
    y = np.array(a.get_array_of_samples())    #  get_array_of_samples()函数将mp3文件读为数组
    #  频道数只有0和1，即左声道和右声道
    if a.channels == 2:    
        y = y.reshape((-1, 2))
    #  即对采样点数进行归一化操作
    if normalized:    
        return np.float32(y) / 2**15
    else:
        return y / 2**8

def DoWork():
    uiDesign.pushButton.setText('测试中')
    uiDesign.pushButton.setEnabled(False)
    QApplication.processEvents()
    serName = uiDesign.cmbPorts.currentText()
    ser = serial.Serial(serName) # "COM1"

    mat = wav_to_np("../hm3/luyin.wav")  # 调用wav_to_np()函数即调用处理wave音频得到的的numpy数组
    mat2 = mp3_to_np("../hm3/luyin.wav")   # 调用mp3_to_np()函数即调用处理mp3音频得到的的numpy数组

    for i, j in zip(range(len(mat)), range(len(mat2))):
        dat = pack('ffffBBBB', *mat[i], *mat2[j], 0x00, 0x00, 0x80, 0x7F)
        ser.write(dat)
        #break
        time.sleep(0.001)
    ser.close()
    uiDesign.pushButton.setText('测试')
    uiDesign.pushButton.setEnabled(True)

wnd.show()
app.exec_()

if __name__ == '__main__':
    readWAV("../hm3/luyin.wav")
    wav_to_np("../hm3/luyin.wav")
    readMP3("../hm3/luyin.wav")
    mp3_to_np("../hm3/luyin.wav")
    DoWork()

